package br.ufrj.cg.controller;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.xml.parsers.ParserConfigurationException;

import br.ufrj.cg.model.StampImage;
import br.ufrj.cg.model.StampLabel;
import br.ufrj.cg.view.MainWindow;

public class MainWindowController {

	private MainWindow mainWindow;

	private int positionX;
	private int positionY;
	
	public MainWindowController(MainWindow paramMainWindow) {

		mainWindow = paramMainWindow;
	}

	public void start() {
		mainWindow.setVisible(true);
		// mainWindow.configure();
		// TODO: Implement
	}

	// TODO Valida��o dos inputs
	
	public void openUploadDialog() throws IOException {
		int returnValue = mainWindow.getImageUploader().showOpenDialog(
				mainWindow);

		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File imageFile = mainWindow.getImageUploader().getSelectedFile();
			loadAsBackground(imageFile.getPath());
		}
	}

//	public void openSaveDialog() throws IOException {
//		int returnValue = mainWindow.getSaveImageDialog().showOpenDialog(mainWindow);
		
//		if(returnValue == J)
//	}
	public void saveImage() {
		ImageWriter.saveImage(mainWindow.getLblBackgroundImageLabel()
				.getStampImage());
		System.out.println("Image saved.");

	}

	public void saveXML() {
		StampXMLWriter xmlWriter;

		try {
			xmlWriter = new StampXMLWriter(mainWindow
					.getLblBackgroundImageLabel().getStampImage());
			xmlWriter.write("output.xml");
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}

	}
	
	

	public void drawOverBackground(String paramStampImagePath)
	{
		StampImage newStamp = new StampImage(paramStampImagePath);
		StampImage background = mainWindow.getLblBackgroundImageLabel().getStampImage();
		
		BufferedImage currentBackground = Utils.toBufferedImage(background.getImage());
		BufferedImage stamp = Utils.toBufferedImage(newStamp.getImage());
		
		ImageIcon imageIcon = ImageProcessing.drawImageOverAnother(stamp, currentBackground, positionX, positionY);
		background.setImageIcon(imageIcon);
		mainWindow.getLblBackgroundImageLabel().setStampImage(background);
		mainWindow.getLblBackgroundImageLabel().load();
	}
	
	
	public void generatePreview(String paramStampImagePath)
	{
		StampImage newStamp = new StampImage(paramStampImagePath);
		BufferedImage srcImage = Utils.toBufferedImage(newStamp.getImage());
		ImageIcon imageIcon = ImageProcessing.generateImageIconPixelByPixel(srcImage);
		drawOverPreview(imageIcon);
	}
	
	public void mirrorPreviewOnX()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		
		ImageIcon imageIcon = ImageProcessing.mirrorOnX(srcImage);
		drawOverPreview(imageIcon);
	}
	
	public void mirrorPreviewOnY()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		
		ImageIcon imageIcon = ImageProcessing.mirrorOnY(srcImage);
		drawOverPreview(imageIcon);
	}
	
	public void rotatePreviewImageBy90Degrees(boolean clockwise)
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon rotatedBy90 = null;
		
		if(clockwise)
		{
			rotatedBy90 = ImageProcessing.rotateBy90Clockwise(srcImage);
		}
		else
		{
			rotatedBy90 = ImageProcessing.rotateBy90AntiClockwise(srcImage);
		}
		
		drawOverPreview(rotatedBy90);
		
	}
	
	public void resizePreviewImage(int newWidth, int newHeight)
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon resized = ImageProcessing.resizeImage(newWidth, newHeight, srcImage);
		drawOverPreview(resized);
	}
	
	public void invertPreviewColors()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon inverted = ImageProcessing.invertColors(srcImage);
		drawOverPreview(inverted);
	}
	
	public void turnPreviewToSepia()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon sepia = ImageProcessing.toSepia(srcImage);
		drawOverPreview(sepia);
	}
	
	public void turnPreviewToGrayScale()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon grayScale = ImageProcessing.toGrayScale(srcImage);
		drawOverPreview(grayScale);
	}
	
	public void turnToPureColor()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
//		ImageIcon pureColor = ImageProcessing.isolateRedComponent(srcImage);
//		drawOverPreview(pureColor);
	}
	
	public void colorizePreview(Color color)
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		
		ImageIcon colorized = null;
		
		if(color == Color.red)
		{
			colorized = ImageProcessing.colorizeToRed(srcImage);
		}
		
		if(color == Color.blue)
		{
			colorized = ImageProcessing.colorizeToBlue(srcImage);
		}
		
		if(color == Color.green)
		{
			colorized = ImageProcessing.colorizeToGreen(srcImage);
		}
		
		drawOverPreview(colorized);
	}
	
	public void addTransparency(int paramAlpha)
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon transparent = ImageProcessing.makeTransparent(srcImage, paramAlpha);
		drawOverPreview(transparent);
	}
	
	public void rotatePreviewImageBy180()
	{
		BufferedImage srcImage = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());
		ImageIcon rotatedBy180 = ImageProcessing.rotateBy180(srcImage);
		drawOverPreview(rotatedBy180);
	}
	
	public void drawOverBackgroundFromPreview()
	{
		Image imageToDraw = mainWindow.getPnlPreview().getImage();
		
		if(imageToDraw != null)
		{
			StampImage background = mainWindow.getLblBackgroundImageLabel().getStampImage();
			
			BufferedImage currentBackground = Utils.toBufferedImage(background.getImage());
			BufferedImage newImageToDraw = Utils.toBufferedImage(mainWindow.getPnlPreview().getImage());

			ImageIcon imageIcon = ImageProcessing.drawImageOverAnother(newImageToDraw, currentBackground, positionX, positionY);

			background.setImageIcon(imageIcon);
			mainWindow.getLblBackgroundImageLabel().setStampImage(background);
			mainWindow.getLblBackgroundImageLabel().load();
		}
	
	}
	
	public void drawOverPreview(ImageIcon imageIcon)
	{
		mainWindow.getPnlPreview().setImage(imageIcon.getImage());
		mainWindow.repaint();
	}
	
	public void resetImage() {
		String path = mainWindow.getLblBackgroundImageLabel().getStampImage().getImagePath();
		ImageIcon im = new ImageIcon(path);
		mainWindow.getLblBackgroundImageLabel().getStampImage().setImageIcon(im);
		mainWindow.getLblBackgroundImageLabel().load();
	}

	private StampLabel createStampLabel(String paramImagePath,
			boolean adjustPositions) {
		StampLabel lblStampLabel = new StampLabel();

		int imageWidth = 128;
		int imageHeight = 128;
		
		if (adjustPositions) {
			positionX = positionX - imageWidth / 2;
			positionY = positionY - imageHeight / 2;
		}

		StampImage stampImage = new StampImage(paramImagePath, imageWidth,
				imageHeight, positionX, positionY);

		lblStampLabel.setLocation(new Point(positionX, positionY));

		lblStampLabel.setSize(imageWidth, imageHeight);
		lblStampLabel.setStampImage(stampImage);
		lblStampLabel.load();

		lblStampLabel.setVerticalAlignment(JLabel.TOP);
		lblStampLabel.setHorizontalAlignment(JLabel.CENTER);
		lblStampLabel.setOpaque(true);
		lblStampLabel.setForeground(Color.yellow);
		lblStampLabel.setBorder(BorderFactory.createLineBorder(Color.green));

		return lblStampLabel;
	}

	public void loadAsBackground(String paramFilePath)
	{
		mainWindow.getLblBackgroundImageLabel().getStampImage().loadImage(paramFilePath);
		mainWindow.getLblBackgroundImageLabel().load();
		
		/*Image image = mainWindow.getLblBackgroundImageLabel().getStampImage().getImage();
		Dimension d = new Dimension(image.getWidth(null), image.getHeight(null));
		mainWindow.getPnlImagePanel().setPreferredSize(d);
		mainWindow.getPnlImagePanel().revalidate();
		mainWindow.getPnlImagePanel().repaint();
		mainWindow.getScrImagePanel().revalidate();
		mainWindow.getScrImagePanel().repaint();*/
		
//		mainWindow.getPnlImagePanel().setSize(d);
	}
	
	
	public MainWindow getMainWindow() {
		return mainWindow;
	}

	public void setMainWindow(MainWindow paramMainWindow) {
		mainWindow = paramMainWindow;
	}
	
	public int getPositionX() {
		return positionX;
	}

	public void setPositionX(int positionX) {
		this.positionX = positionX;
	}

	public int getPositionY() {
		return positionY;
	}

	public void setPositionY(int positionY) {
		this.positionY = positionY;
	}

}
